/* TRN
Copyright (c) 2010, jonoerik
All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
 conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
	disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
	disclaimer in the documentation and/or other materials provided with the distribution.
    * The names of contributors may not be used to endorse or promote products derived from this software without specific
	prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE. */

#include "includes.hpp"

enum glevel {
    glev_setup, //set up start of game
    glev_ingame_countdown_start, //setup countdown to main game
    glev_ingame_countdown, //a countdown to the main game
    glev_ingame, //the main game
    glev_intro_start, //init intro
    glev_intro, //display intro
    glev_help_start, //init help
    glev_help //display help
};

TCODList<actor *> actorlist;
grid *gamegrid;
settings *csettings;

int main()
{
    TCODSystem::setFps(maxfps);
    TCODConsole::disableKeyboardRepeat();
    TCODConsole::setCustomFont("resources/dejavu.png", TCOD_FONT_LAYOUT_TCOD | TCOD_FONT_TYPE_GREYSCALE);
    TCODConsole::initRoot(screenw, screenh, "TRN", false);
    TCODConsole::root->setBackgroundColor(TCODColor::black);
    TCODConsole::root->setForegroundColor(TCODColor::white);
    TCODConsole::root->clear();

    gamegrid = new grid(screenw, screenh);
    backfx *cbackfx = new backfx();
    introfx *cintrofx = new introfx();
    info_countdown *ccountdown = new info_countdown();
    csettings = new settings();

    csettings->loadplayers();
    
    TCOD_key_t key;
    bool printscreendown = false; //was the print screen key held down last frame (used to prevent key repeat on print screen taking too many screenshots)

    //index of winner (-2 if not yet found, -1 if was a draw)
    int winnerindex;

    glevel cglev = glev_intro_start;

    //main loop
    while (! TCODConsole::isWindowClosed() && ! TCODConsole::isKeyPressed(TCODK_ESCAPE)) {
        switch (cglev) {
        case glev_setup:

            TCODConsole::root->clear();

            gamegrid->clear();
            for (int i = 0; i < actorlist.size(); i++) {
	            actorlist.get(i)->init();
	        }

            winnerindex = -2;

            cglev = glev_ingame_countdown_start;

            break;

        case glev_ingame_countdown_start:
            
            ccountdown->init();
            cglev = glev_ingame_countdown;

            break;

        case glev_ingame_countdown:

            //draw game
            TCODConsole::root->clear();
            gamegrid->draw(TCODConsole::root);
            for (int i = 0; i < actorlist.size(); i++) {
	            actorlist.get(i)->draw(TCODConsole::root);
            }
            display_helphint(TCODConsole::root);
            display_winner(TCODConsole::root, winnerindex);
            cbackfx->draw(TCODConsole::root);

            ccountdown->display(TCODConsole::root);
            if (ccountdown->isdone) {
                cglev = glev_ingame;
            }

            TCODConsole::flush();

            key = TCODConsole::checkForKeypress(TCOD_KEY_PRESSED);

            if (key.vk == TCODK_F1) {
                cglev = glev_help_start;
            }
            if (key.vk == TCODK_F2) {
                cglev = glev_setup;
            }

            break;

        case glev_ingame:

            //draw game
            TCODConsole::root->clear();
            gamegrid->draw(TCODConsole::root);
            for (int i = 0; i < actorlist.size(); i++) {
	            actorlist.get(i)->draw(TCODConsole::root);
            }
            display_helphint(TCODConsole::root);
            display_winner(TCODConsole::root, winnerindex);
            cbackfx->draw(TCODConsole::root);

            TCODConsole::flush();

            key = TCODConsole::checkForKeypress(TCOD_KEY_PRESSED);

            //move actors
	        for (int i = 0; i < actorlist.size(); i++) {
	    	    actorlist.get(i)->dostep(key);
	        }

            if (key.vk == TCODK_F1) {
                cglev = glev_help_start;
            }
            if (key.vk == TCODK_F2) {
                cglev = glev_setup;
            }

            if (winnerindex == -2) {
                //check for winner
                int actorsleft = 0;
                actor *lastactor = NULL; //one of the remaining actors; if only one left, then this will be the winner
                for (int i = 0; i < actorlist.size(); i++) {
                    if (actorlist.get(i)->alive) {
                        actorsleft++;
                        lastactor = actorlist.get(i);
                    }
                }
                if (actorsleft == 0) {
                    winnerindex = -1;
                } else if (actorsleft == 1) {
                    winnerindex = lastactor->index;
                }
            }

            break;

        case glev_intro_start:

            cintrofx->init(30);
            TCODConsole::root->clear();
            display_intro(TCODConsole::root);

            cglev = glev_intro;
            break;

        case glev_intro:

            cintrofx->draw(TCODConsole::root);
            TCODConsole::flush();
            key = TCODConsole::checkForKeypress(TCOD_KEY_PRESSED);

            if (key.vk != TCODK_NONE && key.vk != TCODK_PRINTSCREEN) {
                cglev = glev_setup;
            }

            break;

        case glev_help_start:

            cintrofx->init(5);
            TCODConsole::root->clear();
            display_help(TCODConsole::root);
           
            cglev = glev_help;
            break;

        case glev_help:

            cintrofx->draw(TCODConsole::root);
            TCODConsole::flush();
            key = TCODConsole::checkForKeypress(TCOD_KEY_PRESSED);

            if (key.vk != TCODK_NONE && key.vk != TCODK_PRINTSCREEN) {
                cglev = glev_ingame_countdown_start;
            }

            break;
        }

        //screenshot code
        if (TCODConsole::isKeyPressed(TCODK_PRINTSCREEN)) {
            if (!printscreendown) {
                TCODSystem::saveScreenshot(NULL);
            }
            printscreendown = true;
        } else {
            printscreendown = false;
        }

    }
    actorlist.clearAndDelete();
    delete gamegrid;
    delete cbackfx;
    delete cintrofx;
    delete ccountdown;
    delete csettings;
}
